/*
* @Author: wangke
* @Date:   2016-06-02 09:25:53
* @Last Modified by:   wangke
* @Last Modified time: 2016-06-07 16:46:36
*/

#include <stdio.h>
#include "sys/types.h"
#include "sys/socket.h"
#include "string.h"
#include "stdlib.h"
#include "unistd.h"
#include "netinet/in.h"	// struct sockaddr_in 
#include "errno.h"    
#include "pthread.h"         
#include "fcntl.h"        
#include "poll.h"  	

#define  MYPORT	(8888)
#define  LISTEN_MAX_NUM	(32)

static void *echofx(void *arg)
{
	int sockfd = *((int *)arg);
	int ret ;
	int rlen;
	char rbuf[256];
	struct pollfd fd[32];
	int maxfd;
	int timeout;

	printf("[THE] arg  = %d\n", sockfd);

	maxfd = 0;
	timeout = 6000;

	while(1) {

		fd[0].fd = sockfd;
		fd[0].events = POLLIN;

		ret = poll(fd, maxfd+1, timeout);

		if(ret == -1) {
			printf("[THE] select  err\n");

		}
		else if(ret == 0) {
			printf("[THE] select timeout ..\n");
			continue;

		}
		else {

			if(fd[0].revents == POLLIN) {
				rlen = 0;
				memset(rbuf, '\0', sizeof(rbuf));

				rlen = recv(sockfd, rbuf, sizeof(rbuf), 0);
				if(rlen>0) {
				printf("[SRV] recv fd: %d -->  msg: %s\n", sockfd, rbuf);
				send(sockfd, rbuf, strlen(rbuf), 0);
			}

			}
			
		}
	}	
}


int main(int argc, char const *argv[])
{
	struct sockaddr_in srvaddr;
	struct sockaddr_in cliAddr;
	int socket_fd;

	int ret;
	int cliConn = 0;
	socklen_t cliAddrLen;

	pthread_t pth;

	socket_fd = socket(AF_INET, SOCK_STREAM, 0);

	printf("[SRV] socket_fd = %d\n", socket_fd);

	if(socket_fd == -1) {
	 	printf("[SRV] socket err\n");
	 	exit(1);
	}

	printf("[SRV]  000 \n");

	srvaddr.sin_family = AF_INET;
	srvaddr.sin_port = htons(MYPORT);
	srvaddr.sin_addr.s_addr = htonl(INADDR_ANY);

	printf("[SRV]  111 \n");

	ret = bind(socket_fd, (struct sockaddr *)&srvaddr, sizeof(struct sockaddr_in));
	printf("[SRV] %d; ret = %d\n", __LINE__, ret);

	if(ret == -1) {
		printf("[SRV] bind err!, errno = %d\n", errno);
		exit(1);
	}
	printf("[SRV]  222 \n");
	ret = listen(socket_fd, LISTEN_MAX_NUM);
	if(ret == -1) {
		printf("[SRV] listen err\n");
		exit(1);
	}
	printf("[SRV]  333 \n");
	cliAddrLen = sizeof(struct sockaddr_in);

	printf("[SRV] cliAddrLen =%d, cliConn = %d\n", cliAddrLen, cliConn);

	while(1) {

		cliConn = accept(socket_fd, (struct sockaddr *)&cliAddr, &cliAddrLen);
		if(cliConn) {
			printf("[SRV] accept ok...\n");

		// 	if(fork()==0) {

		// 		while(1) {
		// 		    rlen = 0;
		// 			memset(rbuf, '\0', sizeof(rbuf));

		// 			rlen = recv(cliConn, rbuf, sizeof(rbuf), 0);
		// 			if(rlen>0) {
		// 			printf("[SRV] recv msg: %s\n", rbuf);
		// 			send(cliConn, rbuf, strlen(rbuf), 0);

		// 		}
			
		// 	}
		// }

		//  create pthread for more client
		ret = pthread_create(&pth, NULL, echofx, (void *)&cliConn);
		if(ret!=0) {
			printf("[SRV] pthread err, ret = %d\n", ret);
			exit(1);
		}
		else
		{
			printf("[SRV] pthread ok ...\n");
		}
		
		}
	}

	close(cliConn);
	close(socket_fd);

	return 0;
}
